package api

import (
	"context"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"project05_web/src/cache"
	"project05_web/src/forms"
	"project05_web/src/global"
	"project05_web/src/middlewares"
	"project05_web/src/models"
	"project05_web/src/proto"
	"project05_web/src/utils/Sms"
	"strings"
	"time"
)

// 发送手机注册验证码
func RegisterByPhone(c *gin.Context) {
	phone := c.Param("phone")

	//向对应手机号发送短信验证码
	_, err := Sms.SendSMS(phone, 1)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "发送成功",
		"code": 200,
		"data": nil,
	})
}

// 发送手机登录验证码
func LoginByPhone(c *gin.Context) {
	phone := c.Param("phone")

	//向对应手机号发送短信验证码
	_, err := Sms.SendSMS(phone, 2)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"msg":  "发送成功",
		"code": 200,
		"data": nil,
	})
}

// 验证手机号，并且注册用户
func VerifyToPhone(c *gin.Context) {
	//获取表单信息
	var user forms.CreateUserByPhone
	err := c.ShouldBind(&user)
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	res, err := global.RedisDb.Get(context.Background(), user.Phone).Result()
	if err != nil {
		SwitchGrpcErrorToHttp(err, c)
		return
	}

	//获取到验证码id,并且验证是否是手机验证码
	myResp := strings.Split(res, "&amp")
	if myResp[1] != "phonetoregister" {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg":  "验证码无效",
			"data": nil,
			"code": 400,
		})
		return
	}

	res = myResp[0]

	temp := cache.RedisStore{}.Verify(res, user.VCode, true)
	if temp {
		resp, errs := global.UserClient.CreateSmsUser(context.Background(), &proto.SmsInfo{
			Phone:    user.Phone,
			Email:    "",
			Password: user.Password,
			Identify: user.Identify,
			RoleId:   int32(user.RoleId),
		})
		if errs != nil {
			SwitchGrpcErrorToHttp(errs, c)
			return
		}

		c.JSON(http.StatusOK, gin.H{
			"msg":  "注册成功",
			"code": 200,
			"data": resp,
		})
	} else {
		c.JSON(http.StatusInternalServerError, gin.H{
			"msg":  "验证码失效",
			"code": "500",
			"data": nil,
		})
	}
}

// 验证手机号并且登录
func ValidatePhoneCodeToLogin(c *gin.Context) {

	//检验邮箱是否合法
	myPhone := c.Param("phone")
	myVCode := c.Param("vCode")
	// 通过邮箱获取在redis中绑定的id
	id, err := global.RedisDb.Get(context.Background(), myPhone).Result()
	if err != nil {
		log.Println(err.Error())
		c.JSON(http.StatusBadRequest, gin.H{
			"status":           400,
			"msg":              "Redis获取vCode失败",
			"ERROR-CONTROLLER": err.Error(),
		})
		return
	}

	//校验id是否合法
	resp := strings.Split(id, "&amp")
	if resp[1] != "phonetologn" {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg":  "验证码失效",
			"data": nil,
			"code": 400,
		})
		return
	}

	id = resp[0]
	//通过id获取到redis中的验证码
	vCode := myVCode
	res := cache.RedisStore{}.Verify(id, vCode, true)
	if res {
		user, errs := global.UserClient.GetUserByPhone(context.Background(), &proto.PhoneRequest{Phone: myPhone})
		if errs != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"msg":  "邮箱获取用户失败",
				"data": nil,
				"code": 500,
			})
		}
		j := middlewares.NewJWT()
		claims := models.CustomClaims{
			ID:          uint(user.Id),
			UserName:    user.UserName,
			AuthorityId: uint(user.RoleID),
			StandardClaims: jwt.StandardClaims{
				ExpiresAt: time.Now().Unix() + 60*60*24*30,
				Issuer:    "Jo",
				NotBefore: time.Now().Unix(),
			},
		}
		token, err := j.CreateToken(claims)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"msg":  "生成验证码失败",
				"data": nil,
				"code": 500,
			})
		}
		c.JSON(http.StatusOK, gin.H{
			"msg": "登录成功",
			"data": gin.H{
				"x-token": token,
				"user":    user,
			},
			"code": 200,
		})
	} else {
		c.JSON(http.StatusBadRequest, gin.H{
			"status": 400,
			"msg":    "验证失败，验证码已失效",
		})
		return
	}
}
